<?php
include_once $_SERVER['DOCUMENT_ROOT']."/config.php";
include_once "./chatbotConfig.php";
include_once "./config.php";
include_once $_SERVER['DOCUMENT_ROOT'].'/begin.htm';

$topMenuTitle = "홈페이지 학습";

$array = array(
	array("홈페이지 학습",
		"/chat/homepage.htm"),
);
// 메뉴
$code = 'AS1729062288';
include_once $_SERVER['DOCUMENT_ROOT'].'/chat/cate_menu.php';

// PHP 5.5.0
if (!function_exists('array_column')) {
	function array_column($array, $columnKey) {
		$result = array();
		foreach ($array as $subArray) {
			if (isset($subArray[$columnKey])) {
				$result[] = $subArray[$columnKey];
			}
		}
		return $result;
	}
}

// 학습 권한
$isStudyAuth = false;
if ($authCfg['study_auth'] == 'on') {
	$isStudyAuth = true;
} else if ($authCfg['study_auth'] == 'off' && count($authCfg['study_list']) > 0) {
	$isStudyAuth = in_array($member_info['num'], array_column($authCfg['study_list'], 'num'));
} else {
	$isStudyAuth = in_array($member_info['num'], $authCfg['dm']);
}

// 삭제 권한
$isDelAuth = false;
if ($authCfg['del_auth'] == 'on') {
	$isDelAuth = true;
} else if ($authCfg['del_auth'] == 'off' && count($authCfg['delete_list']) > 0) {
	$isDelAuth = in_array($member_info['num'], array_column($authCfg['delete_list'], 'num'));
} else {
	$isDelAuth = in_array($member_info['num'], $authCfg['dm']);
}

if(isMobile()){
?>
<div class="join-date-floor chatC">
	<div class="join-date">
		<h2 style="width: 130px;"><?=$topMenuTitle?></h2>
		<div class="join-date-box">
			<a href="#n" class="mobile-years-btn"><?=$topMenuTitle?> 선택</a>
			<span>
			<?php
				$array_num = count($array);
				for ($i=0; $i < $array_num; $i++)
				{
					$file_name		= $array[$i][1];
					$file_value		= $array[$i][0];

					$br_s = ""; $br_e = "";
					if (strpos($file_name,$PHP_SELF) !== false && !$_GET['m']) {
						$br_s = "<b>"; $br_e = "</b>";
					}
					
					if (strpos($file_name, $_GET['m'])) {
						$br_s = "<b>"; $br_e = "</b>";
					}
					echo "<a href='".$file_name."'>".$br_s." ".$file_value." ".$br_e."</a>".$file_addtxt_r."\n";
				}
			?>
			</span>
		</div>
	</div>
</div>
<?php }else{ ?>
<table width='99%' cellpadding=0 cellspacing=0 border=0 align='center'>
<tr><td height=12 bgcolor='#FFFFFF'></td></tr>
<tr><td height=1 bgcolor='#D9D9D9'></td></tr>
<tr><td height=5 bgcolor='#ffffff'></td></tr>
<tr><td>
	<table cellpadding=0 cellspacing=0 border=0>
	<tr>
		<td valign="middle"><img src="/~AsaProgram/asapro/image/ii.gif" align="absmiddle"><strong><?=$topMenuTitle?></strong> | &nbsp;</td>
		<td align='left'>
			<table cellspacing=0 cellpadding=0 border=0>
				<tr>
			<?php
				$array_num = count($array);
				for ($i=0; $i < $array_num; $i++)
				{
					$file_name		= $array[$i][1];
					$file_value		= $array[$i][0];

					$br_s = ""; $br_e = "";
					if (strpos($file_name,$PHP_SELF) !== false && !$_GET['m']) {
						$br_s = "<b>"; $br_e = "</b>";
					}
					
					if (strpos($file_name, $_GET['m'])) {
						$br_s = "<b>"; $br_e = "</b>";
					}
					echo "<td>&nbsp;&nbsp;".$file_addtxt_f."<img src='/~AsaProgram/asapro/image/i2.gif' align='absmiddle'></td>\n";
					echo "<td><a href='".$file_name."'>".$br_s." ".$file_value." ".$br_e."</a>".$file_addtxt_r."</td>\n";
				}
			?>
				</tr>
			</table>
		</td>
	</tr>
	</table>
</td></tr>
<tr><td height=2 bgcolor='#F7F7F7'></td></tr>
<tr><td height=2 bgcolor='#EAEAEA'></td></tr>
<tr><td height=1 bgcolor='#FFFFFF'></td></tr>
<tr><td height=1 bgcolor='#B6B6B6'></td></tr>
<tr><td height=5><img src='<?=$ASAPRO_URL?>/image/d.gif' style="vertical-align: top;"></td></tr>
<tr><td height=6 bgcolor='#FFFFFF'></td></tr>
</table>
<?php }?>
<style>

	.container {
		/*background-color: #ffffff;
		border-radius: 8px;
		box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
		padding: 20px;
		max-width: 800px;
		width: 100%;
		box-sizing: border-box;*/
	}

	h1 {
		text-align: center;
		margin-bottom: 30px;
		font-size: 24px;
		color: #333;
	}

	textarea {
		width: 100%;
		height: 200px;
		padding: 10px;
		border: 1px solid #ccc;
		border-radius: 4px;
		resize: none;
		font-size: 16px;
		box-sizing: border-box;
	}

	.input-group {
		display: flex;
		flex-direction: column;
		margin-top: 20px;
	}

	input[type="file"],
	input[type="text"] {
		/* margin-bottom: 10px; */
		padding: 10px;
		font-size: 16px;
		border-radius: 4px;
		border: 1px solid #ccc;
		box-sizing: border-box;
	}

	.submit-btn {
		display: block;
		width: 100%;
		margin: 20px 0;
		padding: 6px 10px;
		font-size: 18px;
		border: none;
		border-radius: 4px;
		background-color: #007bff;
		color: #fff;
		cursor: pointer;
		text-align: center;
	}

	.submit-btn:hover {
		background-color: #0056b3;
	}

	.result {
		margin-top: 20px;
		text-align: center;
		font-size: 18px;
		color: #555;
	}

	.token-count {
		text-align: right;
		font-size: 14px;
		color: #666;
		margin-top: 10px;
	}

	.tabs {
		margin-top: 20px;
		display: flex;
		justify-content: space-around;
		border-bottom: 2px solid #ccc;
	}

	.tab {
		padding: 10px 20px;
		cursor: pointer;
		border: 1px solid #ccc;
		border-bottom: none;
		background-color: #f9f9f9;
		color: #007bff;
		font-weight: bold;
	}

	.tab.active {
		background-color: #ffffff;
		border-bottom: 2px solid #ffffff;
	}

	.tab-content {
		display: none;
		margin-top: 20px;
	}

	.tab-content.active {
		display: block;
	}

	.list-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 10px;
		border: 1px solid #ccc;
		border-radius: 4px;
		margin-bottom: 10px;
	}

	.filename {
		max-width: 60%;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.button-group {
		display: flex;
		align-items: center;
	}

	.original-btn {
		background-color: #007bff;
		color: #fff;
		border: none;
		padding: 5px 10px;
		border-radius: 4px;
		cursor: pointer;
		margin-right: 10px;
	}

	.original-btn:hover {
		background-color: #0056b3;
	}

	.delete-btn {
		background-color: #ff4d4d;
		color: #fff;
		border: none;
		padding: 5px 10px;
		border-radius: 4px;
		cursor: pointer;
	}

	.delete-btn:hover {
		background-color: #d43f3f;
	}

	/* Progress Bar 스타일 */
	.progress-bar {
		width: 100%;
		background-color: #f3f3f3;
		border-radius: 4px;
		margin-top: 20px;
		height: 20px;
		overflow: hidden;
	}

	.progress-bar-inner {
		height: 100%;
		width: 0%;
		background-color: #007bff;
		text-align: center;
		line-height: 20px;
		color: white;
		border-radius: 4px;
		transition: width 0.5s ease;
	}
</style>
	<link rel="stylesheet" type="text/css" href="../chat/css/style.css">
	<script language="javascript" src="../chat/js/ai.js"></script>
	<div class="container container-ai">
		<h3 class="h3-title">챗봇 선택
			<?php echo $chatbotSelectBox?>
		</h3>
		<div class="study-box1">
			<div class="lf">
				<div class="study-tit">홈페이지학습 <a href="#n" id="refreshLink"><img src="/~AsaProgram/module/member/image/index/main_table_icon.gif" border="0" title="새로고침" style="cursor:hand"> <span>새로 고침</span></a></div>
				<script>
					document.getElementById("refreshLink").onclick = function(event) {
						event.preventDefault();
						location.reload();
					};
				</script>
				<div class="file2">
					<div class="file-cont2">
						<input type="text" id="siteExplain" placeholder="사이트 설명" class="exp">
						<input type="text" id="singleUrlInput" placeholder="학습할 페이지 URL을 입력하세요">
						<button class="submit-btn save" id="singleUrlsubmit-btn" style="background-color: #bfbfbf;" disabled>가져오기</button>
					</div>
				</div>
				<div class="txt about"><i>※ </i>HTML 페이지의 모든 텍스트 내용을 학습합니다. 단, 이미지 파일과 HTML 코드는 학습하지 않습니다.</div>
				<div class="txt about"><i>※ </i>표 안에 있는 텍스트 내용을 대부분 잘 학습합니다. 다만, 일부 표의 내용은 인식하지 못할 수 있습니다.</div>
				<div class="txt about"><i>※ </i>도메인명이나 폴더명을 입력하면 해당 주소 및 그 하위에 있는 모든 HTML 파일 내용을 수집할 수 있습니다.<br>예) https://company.com/service/ 라는 주소가 있다면, /service 폴더에 있는 모든 HTML 파일 내용을 수집합니다.</div>
				<div class="progress-bar-all">
					<div class="progress-bar" id="progressBar">
						<div class="progress-bar-inner" id="progressBarInner" style="width:0%">0%</div>
					</div>
				</div>
			</div>
			<div class="rt">
				<div class="tit">AI학습</div>
				<div class="progress-bar-all">
					<div class="progress-bar" id="progressBar">
						<div class="progress-bar-inner" id="progressBarInner1" style="width:0%">0%</div>
					</div>
				</div>
				<div class="btn">
					<button class="submit-btn" id="submit-btn" style="background-color: #bfbfbf;" disabled>학 습 하 기</button>
					<button class="submit-btn" id="stopBtn" style="background-color: #bfbfbf;" disabled>중 단 하 기</button>
				</div>
				<div>현재까지 학습된 용량 : <span id="study_size">0</span> / <?php echo $chatbotCfg['study_hp_maxsize']?></div>
			</div>
		</div>
		<div class="study-list">
			<div class="btns">
				<a href="#" onclick="moveFile(1, 'precheckN')">분류이동</a>
				<a href="#" onclick="allPresDeleteUrl();" class="del">삭제하기</a>
			</div>
			<div class="all-table-style chatbro-m t1s-table">
				<table>
					<colgroup>
						<col style="width:25px">
						<col style="width:75px;">
						<col style="width:140px;">
						<col style="width:160px;">
						<col style="width:180px;">
						<col style="width:80px;">
						<col style="width: ">
						<col style="width:80px;">
						<col style="width:150px;">
						<col style="width:80px;">
						<col style="width:170px">
					</colgroup>
					<thead>
						<tr>
							<th scope="col"><input type="checkbox" id="prechkAll" onclick="javascript:precheck();"></th>
							<th scope="col">번호</th>
							<th scope="col">대분류</th>
							<th scope="col">소분류</th>
							<th scope="col">사이트 설명</th>
							<th scope="col">메모</th>
							<th scope="col">학습할 홈페이지 주소 (URL)</th>
							<th scope="col">메모</th>
							<th scope="col">일시</th>
							<th scope="col">용량</th>
							<th scope="col"></th>
						</tr>
					</thead>
					<tbody id="url-pres-list"></tbody>
				</table>
			</div>
		</div>


		<div class="searchBar">
			<div class="btns">
				<a href="#n" onclick="moveFile(2, 'checkN')">분류이동</a>
				<a href="#n" onclick="allRelearn();" id="allRelearn">재학습</a>
				<a href="#n" onclick="allDeleteUrl();" class="del">삭제하기</a>
			</div>
			<div class="rtArea">
				<span>
					<input type="hidden" name="pageMax" id="pageMax" value="20">
					<input type="hidden" name="pageNum" id="pageNum" value="0">
					<input type="text" name="serch_tex" id="serch_tex" value=""><a href="#n" onclick="loadUrlList('N');">검색</a>
					<select name="serch_page" id="serch_page" onchange="loadUrlList('N');">
						<option value="10">10</option>
						<option value="20">20</option>
						<option value="30" selected>30</option>
						<option value="50">50</option>
						<option value="100">100</option>
						<option value="1000">1000</option>
					</select>
				</span>
				<span>
					정렬 
					<select class="file-name" name="serch_pro" id="serch_pro" onchange="loadUrlList('N');">
						<option value="created_at">일시</option>
						<option value="subject">제목</option>
						<option value="all_text">용량</option>
					</select>
					<label><input type="checkbox" name="serch_order" id="serch_order" onclick="loadUrlList('N');">역순</label>
				</span>
			</div>
		</div>
		<div class="study-list">
			<div class="all-table-style chatbro-m t1s-table tt2">
				<div class="all-table-style-uppop">
					<div class="atsu-con atsu2">
						<h3>홈페이지 재학습</h3>
						<p style="font-size: 13px;">기존 홈페이지를 재학습합니다.</p>
						<div class="progress-barAll">
							<div class="progress-bar" id="progressBar3">
								<div class="progress-bar-inner" id="progressBarInner2" style="width:0%">0%</div>
							</div>
						</div>
						<div class="p-btns">
							<!-- <a href="#n" class="y-a" id="y-a">재학습</a> -->
							<a href="#n" class="n-a">닫기</a>
						</div>
					</div>
				</div>
				<table>
					<colgroup>
						<col style="width:25px">
						<col style="width:75px;">
						<col style="width:140px;">
						<col style="width:160px;">
						<col style="width:180px;">
						<col style="width:80px;">
						<col style="width: ">
						<col style="width:80px;">
						<col style="width:150px;">
						<col style="width:80px;">
						<col style="width:170px">
					</colgroup>
					<thead>
						<tr>
							<th scope="col"><input type="checkbox" id="chkAll" onclick="javascript:check();"></th>
							<th scope="col">번호</th>
							<th scope="col">대분류</th>
							<th scope="col">소분류</th>
							<th scope="col">사이트 설명</th>
							<th scope="col">메모</th>
							<th scope="col">학습 완료한 홈페이지 주소 (URL)</th>
							<th scope="col">메모</th>
							<th scope="col">일시</th>
							<th scope="col">용량</th>
							<th scope="col"></th>
						</tr>
					</thead>
					<tbody id="url-list"></tbody>
				</table>
			</div>
		</div>
		<div class="paging" id="paging"></div>

			<!-- 결과 표시 -->
			<div id="result" class="result"></div>
	</div>
</div>

<div class="container-modal" id="modal">
	<div class="modal-content">
		<h2 style="font-size: 20px;">홈페이지 가져오기</h2>
		<p>해당 도메인 또는 폴더 아래에 HTML 페이지가 여러 개 존재합니다.</p>
		<button class="btn-index" style="background-color:gray;" onclick="showModal('index')">한 페이지만 가져오기</button>
		<button class="btn-all" style="background-color:gray;" onclick="showModal('all')">모두 가져오기</button>
		<button class="btn-cancel" style="background-color:gray;" onclick="showModal('cancel')">취소</button>
	</div>
</div>

<div class="container-modal" id="there">
	<div class="modal-content">
		<p id="there_p">이미 동일한 홈페이지 주소가 있습니다. 재학습을 할까요?</p>
		<button class="btn-all" id="there_but">예</button>
		<button class="btn-cancel" onclick="showModal('there')">아니오</button>
	</div>
</div>

<link rel="stylesheet" type="text/css" href="./bounced.css">
<script language="javascript" src="./bounced.js"></script>
<script>
	//전체분류명
	const catejson =<?echo $catejsonData;?>;
	// 페이지 로드 시 실행되는 함수
	window.onload = function() {
		loadUrlList('N');
		loadUrlPresList();
	};
	
	const study_hp_count = '<?php echo $chatbotCfg[study_hp_count]?>' !== '무제한' ? parseInt('<?php echo $chatbotCfg[study_hp_count]?>', 10) : '무제한';
	const study_hp_maxcount = '<?php echo $chatbotCfg[study_hp_maxcount]?>' !== '무제한' ? parseInt('<?php echo $chatbotCfg[study_hp_maxcount]?>', 10) : '무제한';
	const study_hp_size = convertToBytes('<?php echo $chatbotCfg[study_hp_size]?>');
	const study_hp_maxsize = convertToBytes('<?php echo $chatbotCfg[study_hp_maxsize]?>');
	let allDataCnt = 0;
	let allDataSize = 0;

	const progressBarInner = document.getElementById('progressBarInner');
	const progressBarInner1 = document.getElementById('progressBarInner1');
	const progressBarInner2 = document.getElementById('progressBarInner2');
	const siteExplain = document.getElementById('siteExplain');
	const singleUrl = document.getElementById('singleUrlInput');
	const singleSub = document.getElementById('singleUrlsubmit-btn');
	const subBtn	= document.getElementById('submit-btn');
	const stopBtn	= document.getElementById('stopBtn');
	let stopbar = false;
	let abortController;
	let isTaskRunning = false;
	
	//현재 페이지 1차분류
	var cateCode = '<?php echo $code?>';
	//현재 페이지 2차분류
	var cateCode2 = '<?php echo $m?>';
	//분류이동
	function moveFile (tbl, chkn){
		if ($("input[name='"+chkn+"']:checked").length == 0) {
			alert("이동할 파일을 선택해 주세요.");
			return false;
		}
		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		// 선택한 데이터
		var arr = {
			isData: [],
			isCode: cateCode,
			isUrl: './cate_selectbox.php',
			isTable: tbl,
			isThisCate: [],
			isField: 'url_address|url' //홈페이지학습
		};
		$('input[name="' + chkn + '"]:checked').each(function(i) {
			var fileValue = $(this).data('size');
			arr.isData.push(String(fileValue));
			var categoryValue = $(this).siblings('input[name="category"]').val();
			arr.isThisCate.push(categoryValue);
		});

		// 알럿창
		var bounced = new Bounced({
			width:370,
			height:220,
			alerttit:"분류이동",
			setOverflow:"overflow-y:none",
			data:arr
		});
		bounced.show();
	}
	
	// 메모
	function memo(tbl, filename, type) {
		let title = type === 'site' ? '사이트 설명 메모' : '홈페이지 주소 메모';
		
		// 알럿창
		var bounced = new Bounced({
			width: 540,
			height: 270,
			alerttit: title,
			setOverflow: "overflow-y:none",
			html: `<div>
						<span>학습 품질을 향상시키기 위해 ${type === 'site' ? '사이트 설명' : '홈페이지 주소'}에 대한 메모를 입력할 수 있습니다.</span>
						<textarea id="memo_content" style="width: 100%; height: 100px; margin: 10px 0;"></textarea>
						<div class="progress-bar" id="memoProgressBar" style="margin-bottom: 10px;">
							<div class="progress-bar-inner" id="memoProgressBarInner" style="width:0%"></div>
						</div>
						<div class="btns">
							<a href="#n" id="moveSubmit" onclick="saveMemo('${tbl}', '${filename}', '${type}')" style="padding: 7px 20px;">적용</a>
							<a href="#n" id="moveClose" onclick="closeBounced()" style="padding: 7px 20px;">닫기</a>
						</div>
					</div>`
		});
		
		// 기존 메모 내용 가져오기
		getMemo(tbl, filename, type);
		
		bounced.show();
	}
	
	// 메모 저장
	async function saveMemo(tbl, filename, type) {
		const memo_content = document.getElementById('memo_content').value;
		const memoProgressBarInner = document.getElementById('memoProgressBarInner');
		
		// 상태바 초기화
		memoProgressBarInner.style.width = '0%';
		memoProgressBarInner.textContent = '';
		
		const formData = new FormData();
		formData.append('action', 'save');
		formData.append('chat_bot_id', '<?php echo $chat_bot?>');
		formData.append('tbl', tbl);
		formData.append('filename', filename);
		formData.append('memo', memo_content);
		formData.append('type', type);  // 'site' 또는 'url'
		
		try {
			// 상태바 시작 (0% -> 50%)
			memoProgressBarInner.style.backgroundColor = 'green';
			memoProgressBarInner.style.width = '50%';
			memoProgressBarInner.textContent = '50%';
			
			const response = await fetch('./memo_handler.php', {
				method: 'POST',
				body: formData
			});
			
			// 상태바 진행 (50% -> 90%)
			memoProgressBarInner.style.width = '90%';
			memoProgressBarInner.textContent = '90%';
			
			const result = await response.json();
			if (result.status === "success") {
				// 상태바 완료 (100%)
				memoProgressBarInner.style.width = '100%';
				memoProgressBarInner.textContent = '완료되었습니다.';
				
				setTimeout(() => {
					//alert("메모가 저장되었습니다.");
					closeBounced();
					// 목록 새로고침
					if(tbl === '1') {
						loadUrlPresList();
					} else {
						loadUrlList('N');
					}
				}, 500);
			} else {
				alert("메모 저장에 실패했습니다.");
				memoProgressBarInner.style.width = '0%';
				memoProgressBarInner.textContent = '';
			}
		} catch (error) {
			console.error('Error:', error);
			alert("메모 저장 중 오류가 발생했습니다.");
			memoProgressBarInner.style.width = '0%';
			memoProgressBarInner.textContent = '';
		}
	}
	
	// 메모 가져오기
	async function getMemo(tbl, filename, type) {
		const formData = new FormData();
		formData.append('action', 'get');
		formData.append('chat_bot_id', '<?php echo $chat_bot?>');
		formData.append('tbl', tbl);
		formData.append('filename', filename);
		formData.append('type', type);  // 'site' 또는 'url'
		
		try {
			const response = await fetch('./memo_handler.php', {
				method: 'POST',
				body: formData
			});
			
			const result = await response.json();
			if (result.status === "success") {
				document.getElementById('memo_content').value = result.memo;
			}
		} catch (error) {
			console.error('Error:', error);
		}
	}

	// Bounced 창 닫기
	function closeBounced() {
		document.querySelector('.bounced-bg').remove();
	}
	
	function convertToBytes(valueWithUnit) {
		if (valueWithUnit === '무제한') {
			return '무제한';
		}

		const match = valueWithUnit.match(/^(\d+\.?\d*)([a-zA-Z]*)/);
		if (!match) {
			throw new Error('Invalid value format');
		}

		const numericPart = parseFloat(match[1]);
		const unitPart = match[2].toLocaleUpperCase();

		const conversionFactors = {
			'B': 1,
			'KB': 1024,
			'MB': 1024 * 1024,
			'GB': 1024 * 1024 * 1024,
			'TB': 1024 * 1024 * 1024 * 1024
		};

		if (!conversionFactors[unitPart]) {
			throw new Error('Invalid unit');
		}

		return numericPart * conversionFactors[unitPart];
	}

	function isHomePage(url) {
		const parsedUrl = new URL(url);
		return parsedUrl.pathname === '/';
	}

	function check_button(chkc) {
		if(chkc=='save'){
			subBtn.disabled = true;
			subBtn.style.backgroundColor = '#bfbfbf';
			stopBtn.disabled = true;
			stopBtn.style.backgroundColor = '#bfbfbf';
			singleSub.disabled = true;
			siteExplain.disabled = false;
			singleUrlInput.disabled = false;
			if (!singleSub.classList.contains('save')) {
				singleSub.classList.add('save');
			}
		} else if(chkc=='singleSub'){
			subBtn.disabled = true;
			subBtn.style.backgroundColor = '#bfbfbf';
			singleSub.disabled = false;
			if (singleSub.classList.contains('save')) {
				singleSub.classList.remove('save');
			}
			singleSub.style.backgroundColor = '#0056b3';
			siteExplain.disabled = false;
			singleUrlInput.disabled = false;
		} else if(chkc=='subSinBtncheck'){
			if($("input[name='precheckN']:checked").length <= 0){
				subBtn.disabled = true;
				subBtn.style.backgroundColor = '#bfbfbf';
				singleSub.disabled = false;
				if (!singleSub.classList.contains('save')) {
					singleSub.classList.add('save');
				}
				siteExplain.disabled = false;
				singleUrlInput.disabled = false;
			} else {
				subBtn.disabled = false;
				subBtn.style.backgroundColor = '#0056b3';
				singleSub.disabled = true;
				if (singleSub.classList.contains('save')) {
					singleSub.classList.remove('save');
				}
				singleSub.style.backgroundColor = '#bfbfbf';
				siteExplain.value = '';
				siteExplain.disabled = true;
				singleUrlInput.value = '';
				singleUrlInput.disabled = true;
			}
		} else if(chkc=='subBtncheck'){
			if($("input[name='checkN']:checked").length <= 0){
				subBtn.disabled = true;
				subBtn.style.backgroundColor = '#bfbfbf';
				singleSub.disabled = false;
				if (!singleSub.classList.contains('save')) {
					singleSub.classList.add('save');
				}
				siteExplain.disabled = false;
				singleUrl.disabled = false;
			} else {
				subBtn.disabled = true;
				subBtn.style.backgroundColor = '#bfbfbf';
				singleSub.disabled = true;
				singleSub.style.backgroundColor = '#bfbfbf';
				if (singleSub.classList.contains('save')) {
					singleSub.classList.remove('save');
				}
				siteExplain.value = "";
				siteExplain.disabled = true;
				singleUrl.value = "";
				singleUrl.disabled = true;
			}
		} else if(chkc=='subBtn'){
			subBtn.disabled = false;
			subBtn.style.backgroundColor = '#0056b3';
			singleSub.disabled = true;
			if (singleSub.classList.contains('save')) {
				singleSub.classList.remove('save');
			}
			singleSub.style.backgroundColor = '#bfbfbf';
			siteExplain.disabled = false;
			singleUrlInput.disabled = false;
		}
	}
	
	function check() { 
		$("input[name='checkN']").removeAttr("checked");
		$("input[name='checkN']").prop("checked",$("#chkAll").is(':checked'));
		check_button('subBtncheck');
	}
	
	function precheck() { 
		$("input[name='precheckN']").removeAttr("checked");
		$("input[name='precheckN']").prop("checked",$("#prechkAll").is(':checked'));
		check_button('subSinBtncheck');
	}

	// 진행률 바 초기화
	function resetProgressBar() {
		progressBarInner.style.width = '0%';
		progressBarInner.textContent = '0%';
		progressBarInner.style.backgroundColor = '#f3f3f3';
		progressBarInner1.style.width = '0%';
		progressBarInner1.textContent = '0%';
		progressBarInner1.style.backgroundColor = '#f3f3f3';
		progressBarInner2.style.width = '0%';
		progressBarInner2.textContent = '0%';
		progressBarInner2.style.backgroundColor = '#f3f3f3';
	}

	// Progress Bar 업데이트
	async function updateProgressBar(progressBar, job_id, obj) {
		return new Promise((resolve, reject) => {
			progressBar.style.backgroundColor = 'green';
			progressBar.style.width = '10%';
			progressBar.textContent = '10%';
			progressBarInner2.style.backgroundColor = 'green';
			progressBarInner2.style.width = '10%';
			progressBarInner2.textContent = '10%';
			try {
				const socket = new WebSocket(`<?=$url?>/progress/${job_id}`);
				socket.onopen = function() { learn(obj); };
				let progress;
				socket.onmessage = function(event) {
					const jsonString = JSON.parse(event.data);
					const data = JSON.parse(jsonString);
					if (data.status == 'cancelled' || data.status == 'error' || data.close ) {
						socket.close();
					}
					progress = parseInt(data.progress);
					if (progress >= 98) {
						progressBar.style.backgroundColor = 'green';
						progressBar.style.width = '98%';
						progressBar.textContent = '98%';
						progressBarInner2.style.backgroundColor = 'green';
						progressBarInner2.style.width = '98%';
						progressBarInner2.textContent = '98%';
					} else {
						// 학습 중단 처리

						if (stopbar) {
							cancel_learn(job_id);
							stopbar = false;
							obj.status='N';
						} else {
							stopBtn.disabled = false;
							stopBtn.style.backgroundColor = '#ff4d4d';
						}
						if (parseInt(progressBar.style.width) < progress) {
							progressBar.style.backgroundColor = 'green';
							progressBar.style.width = progress + '%';
							progressBar.textContent = progress + '%';
							progressBarInner2.style.backgroundColor = 'green';
							progressBarInner2.style.width = progress + '%';
							progressBarInner2.textContent = progress + '%';
						}
					}
				};
				socket.onclose = function() {
					stopBtn.disabled = true;
					stopBtn.style.backgroundColor = '#bfbfbf';
					learn_url_add(obj, '');
					resolve();
				};
				socket.onerror = function(err) {
					socket.close();
					reject(err);
				};
			}  catch (error) {
				console.log(error);
				reject(err);
			}
		});
	}

	siteExplain.addEventListener('input', function() {
		const exp = siteExplain.value;
		const url = singleUrl.value;
		if (exp && isValidURL(url)) {
			check_button('singleSub');
		} else {
			check_button('save');
		}
	});
	singleUrl.addEventListener('input', function() {
		const exp = siteExplain.value;
		const url = singleUrl.value;
		if (exp && isValidURL(url)) {
			check_button('singleSub');
		} else {
			check_button('save');
		}
	});

	function isValidURL(url) {
		try {
			new URL(url);
			return true;
		} catch (error) {
			return false;
		}
	}
	
	function showModal(type) {
		let message = '';
		switch (type) {
			case 'index':
				handleSingleSubClick('single');
				document.getElementById('modal').style.display = 'none';
				break;
			case 'all':
				handleSingleSubClick('all');
				document.getElementById('modal').style.display = 'none';
				break;
			case 'cancel':
				document.getElementById('modal').style.display = 'none';
			case 'there':
				document.getElementById('there').style.display = 'none';
				break;
		}
	}
	
	function hasFileExtension(url) {
		const extregex = /\.(html|php|asp|jsp|aspx|js|jsx|py|java|ts|tsx|cshtml|htm)\b/i;
		const hasregex = /\?/;
		if (extregex.test(url)) {
			return true;
		} else {
			return hasregex.test(url);
		}
	}
	
	//URL 내용 저장
	async function handleSingleSubClick(ss = null) {
		const url = singleUrl.value;
		const site= siteExplain.value;
		const import_hp_count = '<?php echo $chatbotCfg[import_hp_count]?>' !== '무제한' ? parseInt('<?php echo $chatbotCfg[import_hp_count]?>', 10) : '무제한';
		const import_hp_size = convertToBytes('<?php echo $chatbotCfg[import_hp_size]?>');
		const now = Date.now();
		nowStop = now;
		if (site.trim() === "") {
			alert("사이트 설명을 입력하세요.");
			siteExplain.focus();
			return false;
		}
		var type = "";
		if (url.trim() === "") {
			alert("학습할 페이지 URL을 입력하세요.");
			singleUrl.focus();
			return false;
		}
		
		if (ss === false && hasFileExtension(url) === false) {
			document.querySelector('#modal').style.display = 'block';
			return false;
		}

		try {
			progressBarInner.style.backgroundColor = 'green';
			progressBarInner.style.width = '10%';
			progressBarInner.textContent = '10%';
			if (ss == 'all') {
				/*stopBtn.disabled = false;
				stopBtn.style.backgroundColor = '#ff4d4d';*/
				type = 'all';
			} else {
				type = 'single';
			}
			let texns = [];
			let texts = [];
			texns.push(site);
			texts.push(url);
			var obj = {
				chat_bot_id: '<?php echo $chat_bot?>',
				subjects: texns,
				contents: texts,
				content_type: 'url',
				status: 'N',
				type: type,
				cnt: import_hp_count,
				size: import_hp_size,
				now: now
			}
			// Create a new AbortController
			abortController = new AbortController();
			const response = await fetch('./learn_url_add.php', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
				},
				body: JSON.stringify(obj),
				signal: abortController.signal, // Pass the abort signal
			});
			//const result = await response.json();
			const reader = response.body.getReader();
			const decoder = new TextDecoder();
			let result = '';
			while (true) {
				const { done, value } = await reader.read();
				if (done) {
					loadUrlPresList(); // URL 목록 갱신
					break;
				}
				// Decode the streamed data
				result += decoder.decode(value, { stream: true });
				// Parse progress and links
				try {
					const data = JSON.parse(result);
					/*if (data.status === "there") {
						if (data.message.indexOf('재학습') !== -1) {
							document.getElementById('there').style.display = 'block';
							let element = document.getElementById('there_but');
							if (data.cate1 != null && data.cate2 != null && data.cate1 != '' && data.cate2 != '') {
								element.onclick = function() {
									relearn(url,site,data.cate1,data.cate2);
								};
							} else {
								element.onclick = function() {
									relearn(url,site);
								};
							}
						} else {
							alert(data.message);
						}
					} else if (data.status === "none") {
						resetProgressBar();
						alert(data.message);
						stopBtn.disabled = true;
						stopBtn.style.backgroundColor = '#bfbfbf';
						singleSub.disabled = true;
						singleSub.style.backgroundColor = '#bfbfbf';
						return false;
					}*/
					if (data.progress > 98) {
						progressBarInner.style.width = '98%';
						progressBarInner.textContent = '98%';
						stopBtn.disabled = true;
						stopBtn.style.backgroundColor = '#bfbfbf';
					} else {
						progressBarInner.style.backgroundColor = 'green';
						progressBarInner.style.width = `${data.progress}%`;
						progressBarInner.textContent = `${data.progress}%`;
					}
					result = ''; // Clear buffer
				} catch (error) {
					console.error('Error parsing JSON:', error);
				}
			}

			/*if (result.status === "success") {
				progressBarInner.style.backgroundColor = 'green';
				progressBarInner.style.width = '90%';
				progressBarInner.textContent = '90%';
				setTimeout(function() {
					loadUrlPresList(); // URL 목록 갱신
				}, 1000);
			} else if (result.status === "there") {
				if (result.message.indexOf('재학습') !== -1) {
					document.getElementById('there').style.display = 'block';
					let element = document.getElementById('there_but');
					if (result.cate1 != null && result.cate2 != null && result.cate1 != '' && result.cate2 != '') {
						element.onclick = function() {
							relearn(url,site,result.cate1,result.cate2);
						};
					} else {
						element.onclick = function() {
							relearn(url,site);
						};
					}
				} else {
					alert(result.message);
				}
			} else if (result.status === "none") {
				resetProgressBar();
				alert(result.message);
			} else if (result.status === "stop") {
				resetProgressBar();
				alert(result.message);
				loadUrlPresList(); // URL 목록 갱신
			} else {
				//document.getElementById('result').innerText = "오류가 발생했습니다.";
			}*/
		} catch (error) {
			console.log(error);
			//document.getElementById('result').innerText = "오류가 발생했습니다.";
			resetProgressBar();
		}
		check_button('save');
		siteExplain.value = "";
		singleUrl.value = "";
	}
	
	singleSub.addEventListener('click', function() {
		handleSingleSubClick(false);
	});

	// 페이지 URL 학습 처리
	subBtn.addEventListener('click', async function() {
		<?php
		if(!$isStudyAuth){
			echo 'alert("학습 권한이 없습니다.");return;'.PHP_EOL;
		}
		?>
		var tex='';
		var checle = $("input[name='precheckN']:checked").length;
		var bsTotal = 0;
		
		if (checle > study_hp_count && study_hp_count != '무제한') {
			alert("1회 최대 학습 개수(<?php echo $chatbotCfg['study_hp_count']?>개) 을 초과하였습니다.");
			return;
		}
		
		if(checle <= 0){
			alert("학습할 홈페이지를 하나 이상 선택해 주세요.");
			return;
		} else {
			let ids = [];
			let urls = [];
			let subs = [];
			$('input[name=precheckN]:checked').each(function(index) {
				ids.push($(this).data('size'));
				urls.push($(this).val());
				subs.push($(this).siblings('input[name="subject"]').val());
				var bytesize = $(this).siblings('input[name="bytesize"]').val();
				bsTotal += parseInt(bytesize, 10);
			});
			
			if (bsTotal > study_hp_size && study_hp_size != '무제한') {
				alert("1회 최대 학습 용량(<?php echo $chatbotCfg['study_hp_size']?>) 을 초과하였습니다.");
				return;
			}
			
			if (allDataCnt > study_hp_maxcount && study_hp_maxcount != '무제한') {
				alert("전체 최대 학습 개수(<?php echo $chatbotCfg['study_hp_maxcount']?>개)을 초과하였습니다.");
				return false;
			}
			
			if (allDataSize > study_hp_maxsize && study_hp_maxsize != '무제한') {
				alert("전체 최대 학습 용량(<?php echo $chatbotCfg['study_hp_maxsize']?>)을 초과하였습니다.");
				return false;
			}
			submit_study(urls, subs, ids, 'S');
		}
	});

	function submit_study_sing(url, text, id, type, bytesize = 0) {
		if (bytesize > study_hp_size && study_hp_size != '무제한') {
			alert("1회 최대 학습 용량(<?php echo $chatbotCfg['study_hp_size']?>) 을 초과하였습니다.");
			return;
		}
		
		if (allDataSize > study_hp_maxsize && study_hp_maxsize != '무제한') {
			alert("전체 최대 학습 용량(<?php echo $chatbotCfg['study_hp_maxsize']?>)을 초과하였습니다.");
			return false;
		}
		let ids = [];
		let urls = [];
		let subs = [];
		ids.push(id);
		urls.push(url);
		subs.push(text);
		submit_study(urls, subs, ids, type);
	}

	async function submit_study(url, subj, ids, type) {

		<?php
		if(!$isStudyAuth){
			echo 'alert("학습 권한이 없습니다.");return;'.PHP_EOL;
		}
		?>
		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		const job_id = generateUUID();
		var obj = {
			chat_bot_id: '<?php echo $chat_bot?>',
			db_name: '<?echo $asapro2_db_info["db_name"];?>',
			content_type: 'url',
			id: ids,
			status: 'Y',
			contents: url,
			subjects: subj,
			state: type,
			job_id: job_id
		}
		isTaskRunning = true;
		await updateProgressBar(progressBarInner1, job_id, obj);
		isTaskRunning = false;
	}

	function generateUUID() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			const r = (Math.random() * 16) | 0;
			const v = c === 'x' ? r : (r & 0x3) | 0x8;
			return v.toString(16);
		});
	}

	// 학습 중단 처리
	stopBtn.addEventListener('click', async function() {
		if (abortController) {
			abortController.abort(); // Abort the fetch request
		}
		stopbar = true;
	});
	
	async function cancel_learn(job_id) {
		check_button('save');
		const response = await fetch(`<?=$url?>/cancel_learn/${job_id}`, {
			method: 'POST'
		});
		const result = await response.json();
		if (result.status === "success") {
			resetProgressBar();
			alert('학습이 중단되었습니다.');
			loadUrlList('N'); // URL 목록 갱신
			loadUrlPresList();
		} else {
			resetProgressBar();
			document.getElementById('result').innerText = "오류가 발생했습니다.";
		}
	}

	// URL 목록 로드
	async function loadUrlList(pagingYn) {
		var isCateCode = '<?php echo $m?>';
		var pageNum = document.getElementById('pageNum').value;
		var serch_tex = document.getElementById('serch_tex').value;
		var serch_page = document.getElementById('serch_page').value;
		var serch_pro = document.getElementById('serch_pro').value;
		var serch_order = document.getElementById('serch_order');
		var order;
		if (pagingYn != 'Y') {
			document.getElementById('pageNum').value = 0;
			pageNum = 0;
		}
		if (serch_order.checked){
			if (serch_pro == 'subject') {
				order = 'DESC';
			} else {
				order = 'ASC';
			}
		} else {
			if (serch_pro == 'subject') {
				order = 'ASC';
			} else {
				order = 'DESC';
			}
		}
		const urlList = document.getElementById('url-list');
		urlList.innerHTML = "";
		const formData = new FormData();
		formData.append('chat_bot_id', '<?php echo $chat_bot?>');
		formData.append('cate', isCateCode);
		formData.append('pageNum', pageNum);
		formData.append('serch_tex', serch_tex);
		formData.append('serch_page', serch_page);
		formData.append('serch_pro', serch_pro);
		formData.append('serch_order', order);
		formData.append('content_type', 'url');
		formData.append('status', 'Y');
		try {
			const response = await fetch('./learn_list.php', {
				method: 'POST',
				body: formData
			});
			const urls = await response.json();
			var length = urls.data.length;
			var url_coun = urls.coun;
			allDataCnt = urls.total;
			if (length <= 0) {
				const item = document.createElement('tr');
				item.innerHTML =
					`<td colspan="11">해당하는 내용이 없습니다.</td>`;
				urlList.appendChild(item);
			} else {
				let totalUrlSize = 0;
				length = url_coun - parseInt(pageNum) * parseInt(serch_page);
				urls.data.forEach(url => {
					const item = document.createElement('tr');
					var getByte = formatBytes(url.size, 'kb');
					totalUrlSize += url.size;
					if (url.cate1 != null && url.cate2 != null && url.cate1 != 'null' && url.cate2 != 'null') {
						cate1 = url.cate1;
						cate2 = url.cate2;
					} else {
						cate1 = '';
						cate2 = '';
					}
					item.innerHTML =`<td class="td-ck"><input type="checkbox" name="checkN" value="${url.content}" onclick="check_button('subBtncheck');" data-size="${url.id}"><input type="hidden" name="subject" value="${url.subject}"></td><td class="td-num">${length}</td><td class="td-bclass">${(cate1 != '')?catejson[cate1]:'-'}</td><td class="td-sclass">${(cate2 != '')?catejson[cate2]:'-'}</td><td class="td-name"><div class='td-hover'>${url.subject}</div></td><td class="td-memo"><a href="javascript:void(0);" onclick="memo(2, '${url.content}', 'site');"><img src="./memo.png"></a></td><td class="td-url2"><div class='td-hover'><a href="${url.content}" target="_blank" class="txt-disabled">${url.content}</a></div></td><td class="td-memo"><a href="javascript:void(0);" onclick="memo(2, '${url.content}', 'url');"><img src="./memo.png"></a></td><td class="td-date">${url.created_at}</td><td class="td-bytes">${getByte}</td><td class="td-btns"><div class="btns"><a href="#n" onclick="relearn_sing('${url.content}','${url.subject}','${url.id}');" class="cover">재학습</a><a href="#n" class="del" onclick="deleteUrl_sing('${url.content}', '${url.id}')">삭제하기</a></div></td>`;
					urlList.appendChild(item);
					length --;
					$(".all-table-style td").on("mouseenter", function(e){
						var ttx = $(this).children("div.td-hover").html();  
						var aaaa=$(this).append("<div class='ttx'>" + ttx + "</div>");
						var tdtdtd=aaaa.outerWidth();
						var divdivdiv=$(this).children("div.ttx").outerWidth() - 10;
						if(divdivdiv >= tdtdtd){
							if($(this).children("div").hasClass("td-hover")){
								if (!$(this).data("hovered")) {
									$(this).children("div.ttx").css({left:"50%"});
									$(this).data("hovered", true);  
								}
							}
						}else{
							$(".all-table-style td").data("hovered", false);
							$(this).children("div.ttx").css({left:"-9999em"});
							$(this).find("div.ttx").remove();
						}
					});
					$(".all-table-style td").on("mouseleave", function(e){
						$(".all-table-style td").data("hovered", false);
						$(this).find("div.ttx").remove();
					});

				});
				
				allDataSize = totalUrlSize;
				document.getElementById('study_size').innerHTML = formatBytes(totalUrlSize, true);
				
				if (parseInt(progressBarInner1.style.width) > 10) {
					progressBarInner1.style.backgroundColor = '#007bff';
					progressBarInner1.style.width = '100%';
					progressBarInner1.textContent = '모두 완료되었습니다.';
					progressBarInner2.style.backgroundColor = '#007bff';
					progressBarInner2.style.width = '100%';
					progressBarInner2.textContent = '모두 완료되었습니다.';
					setTimeout(function() {
						resetProgressBar();
						$(".all-table-style-uppop").fadeOut("fast");
					}, 2000);
				}
				$("#chkAll").attr('checked',false);
				check();
				$("#prechkAll").attr('checked',false);
				precheck();
			}
			//페이징
			paging(url_coun);
		} catch (error) {
			//document.getElementById('result').innerText = "오류가 발생했습니다.";
			resetProgressBar();
			const item = document.createElement('tr');
			item.innerHTML =
				`<td colspan="11">해당하는 내용이 없습니다.</td>`;
			urlList.appendChild(item);
		}

		$(document).ready(function(){
			$(".all-table-style-uppop").on("click", function(){
				$(".all-table-style-uppop").fadeOut("fast");
			});
			$(".n-a").on("click", function(){
				$(".all-table-style-uppop").fadeOut("fast");
			});
			$(".atsu-con").on("click", function(e){
				e.stopPropagation();
			});
			
			<?php if($isStudyAuth){ ?>
			$(".all-table-style td .btns .cover").bind("click", function(e){
				$(".all-table-style-uppop").css({display:"flex"});
			});
			<?php } ?>
				
			$(".all-table-style td .btns .relearn").on("click", function(){
				if($(this).hasClass("on")){
					$(this).parents("tr").find("input[type='text']").prop("disabled","disabled");
					$(this).parents("tr").find("input[type='text']").removeClass("on");
					$(this).removeClass("on");
				}else{
					$(this).parents("tr").find("input[type='text']").prop("disabled","");
					$(this).parents("tr").find("input[type='text']").addClass("on");
					$(this).addClass("on");
				}
			});
		});
	}

	// URL 가져오기 목록 로드
	async function loadUrlPresList() {
		var isCateCode = '<?php echo $m?>';
		const urlList = document.getElementById('url-pres-list');
		urlList.innerHTML = "";
		const formData = new FormData();
		formData.append('chat_bot_id', '<?php echo $chat_bot?>');
		formData.append('cate', isCateCode);
		formData.append('content_type', 'url');
		formData.append('status', 'N');
		try {
			const response = await fetch('./learn_list.php', {
				method: 'POST',
				body: formData
			});
			const urls = await response.json();
			var length = urls.data.length;
			if (length <= 0) {
				const item = document.createElement('tr');
				item.innerHTML =
					`<td colspan="11">해당하는 내용이 없습니다.</td>`;
				urlList.appendChild(item);
			} else {
				urls.data.forEach(url => {
					const item = document.createElement('tr');
					var getByte = formatBytes(url.size, 'kb');
					var bytesize = formatBytes(url.size, false);
					if (url.cate1 != null && url.cate2 != null && url.cate1 != 'null' && url.cate2 != 'null') {
						cate1 = url.cate1;
						cate2 = url.cate2;
					} else {
						cate1 = '';
						cate2 = '';
					}
					item.innerHTML =`<td class="td-ck"><input type="checkbox" name="precheckN" value="${url.content}" onclick="check_button('subSinBtncheck');" data-size="${url.id}"><input type="hidden" name="bytesize" value="${bytesize}"><input type="hidden" name="subject" value="${url.subject}"><input type="hidden" name="category" value="${cate1}|${cate2}"></td><td class="td-num">${length}</td><td class="td-bclass">${(cate1 != '')?catejson[cate1]:'-'}</td><td class="td-sclass">${(cate2 != '')?catejson[cate2]:'-'}</td><td class="td-name"><div class='td-hover'>${url.subject}</div></td><td class="td-memo"><a href="javascript:void(0);" onclick="memo(1, '${url.content}', 'site');"><img src="./memo.png"></a></td><td class="td-url"><div class='td-hover'><a href="${url.content}" target="_blank" class="txt-disabled">${url.content}</a></div></td><td class="td-memo"><a href="javascript:void(0);" onclick="memo(1, '${url.content}', 'url');"><img src="./memo.png"></a></td><td class="td-date">${url.created_at}</td><td class="td-bytes">${getByte}</td><td class="td-btns"><div class="btns"><a href="#n" class="del" onclick="submit_study_sing('${url.content}', '${url.subject}', '${url.id}', 'S', ${bytesize});">학습하기</a><a href="#n" class="del" onclick="deletepresUrl_sing('${url.id}')">삭제하기</a></div></td>`;
					urlList.appendChild(item);
					length --;
					$(".all-table-style td").on("mouseenter", function(e){
						var ttx = $(this).children("div.td-hover").html();  
						var aaaa=$(this).append("<div class='ttx'>" + ttx + "</div>");
						var tdtdtd=aaaa.outerWidth();
						var divdivdiv=$(this).children("div.ttx").outerWidth() - 10;
						if(divdivdiv >= tdtdtd){
							if($(this).children("div").hasClass("td-hover")){
								if (!$(this).data("hovered")) {
									$(this).children("div.ttx").css({left:"50%"});
									$(this).data("hovered", true);  
								}
							}
						}else{
							$(".all-table-style td").data("hovered", false);
							$(this).children("div.ttx").css({left:"-9999em"});
							$(this).find("div.ttx").remove();
						}
					});
					$(".all-table-style td").on("mouseleave", function(e){
						$(".all-table-style td").data("hovered", false);
						$(this).find("div.ttx").remove();
					});
				});
				if (parseInt(progressBarInner.style.width) > 10) {
					progressBarInner.style.backgroundColor = '#007bff';
					progressBarInner.style.width = '100%';
					progressBarInner.textContent = '모두 완료되었습니다.';
					setTimeout(function() {
						resetProgressBar();
					}, 2000);
				}
				$("#chkAll").attr('checked',false);
				check();
				$("#prechkAll").attr('checked',false);
				precheck();
			}
		} catch (error) {
			const item = document.createElement('tr');
			item.innerHTML =
				`<td colspan="11">해당하는 내용이 없습니다.</td>`;
			urlList.appendChild(item);
		}
	}
	
	function newOpen(url) {
		window.location.href=url;
	}
	
	// 전체 재학습 처리
	function allRelearn() {
		if($("input[name='checkN']:checked").length <= 0){
			alert("하나 이상 선택해 주세요.");
			return;
		} else {
			$("#allRelearn").bind("click", function(e){
				$(".all-table-style-uppop").css({display:"flex"});
			});
			let ids = [];
			let urls = [];
			let subs = [];
			$('input[name=checkN]:checked').each(function() {
				ids.push($(this).data('size'));
				urls.push($(this).val());
				subs.push($(this).siblings('input[name="subject"]').val());
			});
			relearn(urls, subs, ids);
		}
		check_button('save');
	}

	function relearn_sing(url, subj, id) {
		let ids = [];
		let urls = [];
		let subs = [];
		ids.push(id);
		urls.push(url);
		subs.push(subj);
		relearn(urls, subs, ids);
	}
	
	// URL 재학습
	async function relearn(url, subj, ids) {
		<?php
		if(!$isStudyAuth){
			echo 'alert("학습 권한이 없습니다.");return;'.PHP_EOL;
		}
		?>
		showModal('there');
		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		stopBtn.disabled = true;
		stopBtn.style.backgroundColor = '#bfbfbf';
		var obj = {
			chat_bot_id: '<?php echo $chat_bot?>',
			db_name: '<?echo $asapro2_db_info["db_name"];?>',
			contents: url,
		}
		try {
			const response = await fetch('<?=$url?>/learn_del', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
				},
				body: JSON.stringify(obj)
			});
			const result = await response.json();
			if (result.status === "success") {
				submit_study(url, subj, ids, 'M');
			} else {
				document.getElementById('result').innerText = "오류가 발생했습니다.";
			}
		} catch (error) {
			resetProgressBar();
			document.getElementById('result').innerText = "오류가 발생했습니다.";
		}
	}
	
	// 전체 학습완료 URL 삭제 처리
	function allDeleteUrl() {
		<?php
		if(!$isDelAuth){
			echo 'alert("삭제 권한이 없습니다.");return;'.PHP_EOL;
		}
		?>

		var url = '', site = '', getByte = '';
		if($("input[name='checkN']:checked").length <= 0){
			alert("하나 이상 선택해 주세요.");
			return;
		} else {
			$('input[name=checkN]:checked').each(async function(index) {
				url += (!url)?$(this).val().split("|")[0]:'|'+$(this).val().split("|")[0];
				site += (!site)?$(this).val().split("|")[1]:'|'+$(this).val().split("|")[1];
				getByte += (!getByte)?$(this).val().split("|")[2]:'|'+$(this).val().split("|")[2];
			});
			deleteUrl(url,site,getByte);
		}
		check_button('save');
	}

	function deleteUrl_sing(url, id) {
		let ids = [];
		let urls = [];
		ids.push(id);
		urls.push(url);
		deleteUrl(urls,ids);
	}

	// URL 삭제 처리
	async function deleteUrl(urls,ids) {
		<?php
		if(!$isDelAuth){
			echo 'alert("삭제 권한이 없습니다.");return;'.PHP_EOL;
		}
		?>

		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		if (confirm('정말 삭제하시겠습니까?')) {
			var obj = {
				chat_bot_id: '<?php echo $chat_bot?>',
				db_name: '<?echo $asapro2_db_info["db_name"];?>',
				contents: urls,
				status: 'D',
				id: ids
			}
			try {
				const response = await fetch('<?=$url?>/learn_del', {
					method: 'POST',
					headers: {
						'Content-Type': 'application/json',
					},
					body: JSON.stringify(obj)
				});
				const result = await response.json();
				if (result.status === "success") {
					learn_url_add(obj, 'url');
				} else {
					document.getElementById('result').innerText = "오류가 발생했습니다.";
				}
			} catch (error) {
				resetProgressBar();
				document.getElementById('result').innerText = "오류가 발생했습니다.";
			}
		}
	}
	
	// 전체 학습할 URL 삭제 처리
	function allPresDeleteUrl() {
		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		var url = '';
		if($("input[name='precheckN']:checked").length <= 0){
			alert("하나 이상 선택해 주세요.");
			return false;
		} else {
			let ids = [];
			$('input[name=precheckN]:checked').each(function() {
				ids.push($(this).data('size'));
			});
			deletepresUrl(ids);
		}
		check_button('save');
	}

	function deletepresUrl_sing(id) {
		let ids = [];
		ids.push(id);
		deletepresUrl(ids);
	}

	// URL 삭제 처리
	async function deletepresUrl(ids) {
		subBtn.disabled = true;
		subBtn.style.backgroundColor = '#bfbfbf';
		if (confirm('정말 삭제하시겠습니까?')) {
			var obj = {
				chat_bot_id: '<?php echo $chat_bot?>',
				status: 'D',
				id: ids
			}
			learn_url_add(obj, 'Pres');
		}
	}

	async function learn_url_add(obj, type) {
		const response = await fetch('./learn_url_add.php', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify(obj)
		});
		const result = await response.json();
		if (result.status === "success") {
			if (type == 'Pres') {
				loadUrlPresList();
			} else if (type == 'url') {
				loadUrlList();
			} else {
				loadUrlList('N');
				loadUrlPresList();
			}
		} else {
			resetProgressBar();
		}
	}

	async function learn(obj) {
		const response = await fetch('<?=$url?>/learn', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify(obj)
		});
		const result = await response.json();

		if (result != null && result.status === "OK") {
		} else {
			resetProgressBar();
			stopBtn.disabled = true;
			stopBtn.style.backgroundColor = '#bfbfbf';
			alert("오류가 발생했습니다.");
		}
	}

	// 탭 전환 기능
	document.querySelectorAll('.tab').forEach(tab => {
		tab.addEventListener('click', function() {
			document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
			document.querySelectorAll('.tab-content').forEach(tc => tc.classList.remove('active'));
			this.classList.add('active');
			document.getElementById(this.dataset.tab).classList.add('active');
		});
	});
	
	function getByteSize(str, kb) {
		const byteCount = new Blob([str]).size;
		return formatBytes(byteCount, kb);
	}
	
	function formatBytes(bytes,kb){
		if(bytes == 0)return "0 Bytes";
		if (kb) {
			var c=1024,
			sizes=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],
			f=Math.floor(Math.log(bytes)/Math.log(c));
			var byt = parseFloat((bytes/Math.pow(c,f)).toFixed(2)).toString();
			if(sizes[f] == "KB" || sizes[f] == "Bytes"){
				byt = parseFloat((bytes/Math.pow(c,f)).toFixed(0)).toString();
			}
			return byt+sizes[f];
		} else {
			return bytes;
		}
	}

	function paging(allpage) {
		var serch_page = parseInt(document.getElementById('serch_page').value);
		var pageNum = parseInt(document.getElementById('pageNum').value);
		var pageMax = parseInt(document.getElementById('pageMax').value);
		var paging = document.getElementById('paging');
		//시작하는 페이지수
		var startPage = 0;
		var endPage = 0;
		//총 페이지수
		var par = (allpage%serch_page == 0)?parseInt(allpage/serch_page):parseInt(allpage/serch_page)+1;
		//몇번째 단락인지 구함
		var para = parseInt(pageNum/pageMax);
		startPage = para*pageMax;
		startPage = (par < startPage)?par:startPage;
		endPage = startPage + pageMax;
		endPage = (par < endPage)?par:endPage;
		var str = `
			<div class="paging-all clearfix">
				<div class="paging-left">`;
		if (pageNum >= pageMax) {
			str += `<a href="#n" onclick="pageSubmit(${allpage}, 1);"><img src="../images/sub/p_first.png" alt=""></a>`;
			str += `<a href="#n" onclick="pageSubmit(${allpage}, 'before');"><img src="../images/sub/p_prev.png" alt=""></a>`;
		}
		for (var i = startPage+1; i <= endPage; i ++) {
			if ((pageNum+1) == i)  {
				str += `<a href="#n"><strong>${i}</strong></a>`;
			} else {
				str += `<a href="#n" onclick="pageSubmit(${allpage}, ${i});">${i}</a>`;
			}
		}
		if (par > ((para+1)*pageMax)) {
			str += `<a href="#n" onclick="pageSubmit(${allpage}, 'after');"><img src="../images/sub/p_next.png" alt=""></a>`;
			str += `<a href="#n" onclick="pageSubmit(${allpage}, ${par});"><img src="../images/sub/p_last.png" alt=""></a>`;
		}
		str += `
				</div>
			</div>`;
		paging.innerHTML = str;
	}

	function pageSubmit(all, str) {
		var pageNum = parseInt(document.getElementById('pageNum').value);
		var pageMax = parseInt(document.getElementById('pageMax').value);
		if (str == 'before') {
			document.getElementById('pageNum').value = (parseInt(pageNum/pageMax)-1)*pageMax;
			paging(all);
		} else if (str == 'after') {
			document.getElementById('pageNum').value = (parseInt(pageNum/pageMax)+1)*pageMax;
			paging(all);
		} else {
			document.getElementById('pageNum').value = parseInt(str)-1;
		}
		loadUrlList('Y');
	}

	document.getElementById('serch_tex').addEventListener('keypress', function(event) {
		if (event.key === 'Enter') {
			loadUrlList('N');
		}
	});
	window.addEventListener("beforeunload", function (event) {
		if (isTaskRunning) {
			event.returnValue = "페이지를 떠나면 현재 학습이 취소됩니다.";
			return "페이지를 떠나면 현재 학습이 취소됩니다.";
		}
	});
</script>
<?
include_once $_SERVER['DOCUMENT_ROOT']."/end.htm";
?>